FastAPI |
您所在的位置:网站首页 › response_type=code 伪装 › FastAPI |
自定义响应 - HTML、流、文件、其他 默认情况下, FastAPI 将使用 JSONResponse 返回响应。 您可以通过直接返回 Response 来覆盖它,如 Return a Response directly 中所示。 但如果直接返回 Response ,数据不会自动转换,文档也不会自动生成(例如,包括特定的 "media type" ,在HTTP标头 Content-Type 中作为生成的OpenAPI的一部分)。 但你也可以在路径操作装饰器中声明你想要使用的 Response 。 从路径操作函数返回的内容将放入该 Response 内。 如果 Response 具有 JSON 媒体类型 ( application/json ),就像 JSONResponse 和 UJSONResponse 的情况一样,您返回的数据将使用您在路径操作装饰器中声明的任何 Pydantic response_model 自动转换(和过滤)。 Note 如果您使用没有媒体类型的响应类, FastAPI 将期望您的响应没有内容,因此它不会在其生成的 OpenAPI 文档中记录响应格式。 Use ORJSONResponse例如,如果您正在挤压性能,则可以安装并使用 orjson 并将响应设置为 ORJSONResponse 。 导入要使用的 Response 类(子类)并在路径操作装饰器中声明它。 对于大型响应,直接返回 Response 比返回字典要快得多。 这是因为默认情况下, FastAPI 将检查内部的每个项目,并确保它可以使用 JSON 进行序列化,使用教程中解释的相同 JSON Compatible Encoder 。这允许您返回任意对象,例如数据库模型。 但是,如果您确定返回的内容可以使用 JSON 进行序列化,则可以将其直接传递到响应类,并通过在将返回内容传递到响应类之前将其传递到 jsonable_encoder 来避免 FastAPI 产生的额外开销。 from fastapi import FastAPI from fastapi.responses import ORJSONResponse app = FastAPI() @app.get("/items/", response_class=ORJSONResponse) async def read_items(): return ORJSONResponse([{"item_id": "Foo"}])Info 参数 response_class 还将用于定义响应的 "media type" 。 在这种情况下,HTTP 标头 Content-Type 将设置为 application/json 。 它将在 OpenAPI 中进行记录。 Tip ORJSONResponse 目前仅在 FastAPI 中可用,在 Starlette 中不可用。 HTML Response要直接从 FastAPI 返回 HTML 响应,请使用 HTMLResponse 。 Import HTMLResponse. 将 HTMLResponse 作为路径操作装饰器的参数 response_class 传递。 from fastapi import FastAPI from fastapi.responses import HTMLResponse app = FastAPI() @app.get("/items/", response_class=HTMLResponse) async def read_items(): return """ Some HTML in here Look ma! HTML! """Info 参数 response_class 还将用于定义响应的 "media type" 。 在这种情况下,HTTP 标头 Content-Type 将设置为 text/html 。 它将在 OpenAPI 中进行记录。 返回 Response如 Return a Response directly 中所示,您还可以通过返回来直接在路径操作中覆盖响应。 上面的相同示例返回 HTMLResponse ,可能如下所示: from fastapi import FastAPI from fastapi.responses import HTMLResponse app = FastAPI() @app.get("/items/") async def read_items(): html_content = """ Some HTML in here Look ma! HTML! """ return HTMLResponse(content=html_content, status_code=200)Warning 由路径操作函数直接返回的 Response 将不会记录在 OpenAPI 中(例如, Content-Type 将不会记录),并且不会在自动交互文档中可见。 Info 当然,实际的 Content-Type 标头、状态代码等将来自您返回的 Response 对象。 OpenAPI 中的文档并覆盖 Response如果您想覆盖函数内部的响应,但同时在 OpenAPI 中记录 "media type" ,则可以使用 response_class 参数并返回 Response 对象。 然后, response_class 将仅用于记录 OpenAPI 路径操作,但您的 Response 将按原样使用。 直接返回 HTMLResponse例如,它可能是这样的: from fastapi import FastAPI from fastapi.responses import HTMLResponse app = FastAPI() def generate_html_response(): html_content = """ Some HTML in here Look ma! HTML! """ return HTMLResponse(content=html_content, status_code=200) @app.get("/items/", response_class=HTMLResponse) async def read_items(): return generate_html_response()在此示例中,函数 generate_html_response() 已生成并返回 Response 而不是在 str 中返回 HTML。 通过返回调用 generate_html_response() 的结果,您已经返回了一个 Response ,它将覆盖默认的 FastAPI 行为。 但是,当您在 response_class 中也通过了 HTMLResponse 时, FastAPI 将知道如何在 OpenAPI 中将其记录下来,并使用 text/html 将交互式文档记录为 HTML: Available responses以下是一些可用的回复。 请记住,您可以使用 Response 返回任何其他内容,甚至创建自定义子类。 Technical Details 您也可以使用 from starlette.responses import HTMLResponse 。 FastAPI 提供了与 fastapi.responses 相同的 starlette.responses ,只是为了方便开发者。但大多数可用的回复直接来自 Starlette。 Response主要的 Response 类,所有其他响应都继承自它。 可以直接退货。 它接受以下参数: content - str 或 bytes 。 status_code - int HTTP 状态代码。 headers - dict 琴弦。 media_type - str 给出介质类型。例如 "text/html" 。FastAPI (实际上是 Starlette)将自动包含 Content-Length 标头。它还将包括一个 Content-Type 标头,基于 media_type 并附加文本类型的字符集。 from fastapi import FastAPI, Response app = FastAPI() @app.get("/legacy/") def get_legacy_data(): data = """ Apply shampoo here. You'll have to use soap here. """ return Response(content=data, media_type="application/xml") HTMLResponse获取一些文本或字节并返回 HTML 响应,如您在上面所读到的。 PlainTextResponse获取一些文本或字节并返回纯文本响应。 from fastapi import FastAPI from fastapi.responses import PlainTextResponse app = FastAPI() @app.get("/", response_class=PlainTextResponse) async def main(): return "Hello World" JSONResponse获取一些数据并返回 application/json 编码响应。 正如您在上面所读到的,这是 FastAPI 中使用的默认响应。 ORJSONResponse正如您在上面所读到的,使用 orjson 的快速替代 JSON 响应。 UJSONResponse使用 ujson 的替代 JSON 响应。 Warning ujson 在处理某些边缘情况方面不如 Python 的内置实现那么谨慎。 from fastapi import FastAPI from fastapi.responses import UJSONResponse app = FastAPI() @app.get("/items/", response_class=UJSONResponse) async def read_items(): return [{"item_id": "Foo"}]Tip ORJSONResponse 可能是更快的替代方案。 RedirectResponse返回 HTTP 重定向。默认情况下使用 307 状态代码(临时重定向)。 您可以直接退回 RedirectResponse : from fastapi import FastAPI from fastapi.responses import RedirectResponse app = FastAPI() @app.get("/typer") async def redirect_typer(): return RedirectResponse("https://typer.tiangolo.com")或者您可以在 response_class 参数中使用它: from fastapi import FastAPI from fastapi.responses import RedirectResponse app = FastAPI() @app.get("/fastapi", response_class=RedirectResponse) async def redirect_fastapi(): return "https://fastapi.tiangolo.com"如果这样做,那么您可以直接从路径操作函数返回 URL。 在这种情况下,使用的 status_code 将是 RedirectResponse 的默认 307 。 您还可以将 status_code 参数与 response_class 参数结合使用: from fastapi import FastAPI from fastapi.responses import RedirectResponse app = FastAPI() @app.get("/pydantic", response_class=RedirectResponse, status_code=302) async def redirect_pydantic(): return "https://pydantic-docs.helpmanual.io/" StreamingResponse采用异步生成器或普通生成器/迭代器并流式传输响应正文。 from fastapi import FastAPI from fastapi.responses import StreamingResponse app = FastAPI() async def fake_video_streamer(): for i in range(10): yield b"some fake video bytes" @app.get("/") async def main(): return StreamingResponse(fake_video_streamer()) 将 StreamingResponse 与类文件对象一起使用如果您有一个类文件对象(例如 open() 返回的对象),您可以创建一个生成器函数来迭代该类文件对象。 这样,您不必首先在内存中读取所有内容,您可以将该生成器函数传递给 StreamingResponse 并返回它。 其中包括许多与云存储、视频处理等交互的 libraries 。 from fastapi import FastAPI from fastapi.responses import StreamingResponse some_file_path = "large-video-file.mp4" app = FastAPI() @app.get("/") def main(): def iterfile(): # (1) with open(some_file_path, mode="rb") as file_like: # (2) yield from file_like # (3) return StreamingResponse(iterfile(), media_type="video/mp4") 这是生成器函数。它是 "generator function" ,因为它内部包含 yield 语句。 通过使用 with 块,我们确保在生成器函数完成后关闭类文件对象。因此,在完成发送响应后。这个 yield from 告诉函数迭代那个名为 file_like 的东西。然后,对于迭代的每个部分, yield 该部分来自该生成器函数。 所以,它是一个生成器函数,将 "generating" 的工作转移到内部的其他东西。 这样,我们就可以将它放在一个 with 块中,这样就可以确保它在完成后是关闭的。 Tip 请注意,这里由于我们使用不支持 async 和 await 的标准 open() ,因此我们使用普通 def 声明路径操作。 FileResponse异步传输文件作为响应。 采用与其他响应类型不同的一组参数来实例化: path - 要流式传输的文件的文件路径。 headers - 作为字典包含的任何自定义标头。 media_type - 给出媒体类型的字符串。如果未设置,文件名或路径将用于推断媒体类型。 filename - 如果设置,它将包含在响应 Content-Disposition 中。文件响应将包括适当的 Content-Length 、 Last-Modified 和 ETag 标头。 from fastapi import FastAPI from fastapi.responses import FileResponse some_file_path = "large-video-file.mp4" app = FastAPI() @app.get("/") async def main(): return FileResponse(some_file_path)您还可以使用 response_class 参数: from fastapi import FastAPI from fastapi.responses import FileResponse some_file_path = "large-video-file.mp4" app = FastAPI() @app.get("/", response_class=FileResponse) async def main(): return some_file_path在这种情况下,您可以直接从路径操作函数返回文件路径。 自定义响应类您可以创建自己的自定义响应类,继承自 Response 并使用它。 例如,假设您想要使用 orjson ,但包含的 ORJSONResponse 类中未使用一些自定义设置。 假设您希望它返回缩进且格式化的 JSON,因此您想使用 orjson 选项 orjson.OPT_INDENT_2 。 您可以创建一个 CustomORJSONResponse 。您要做的主要事情是创建一个 Response.render(content) 方法,该方法将内容返回为 bytes : from typing import Any import orjson from fastapi import FastAPI, Response app = FastAPI() class CustomORJSONResponse(Response): media_type = "application/json" def render(self, content: Any) -> bytes: assert orjson is not None, "orjson must be installed" return orjson.dumps(content, option=orjson.OPT_INDENT_2) @app.get("/", response_class=CustomORJSONResponse) async def main(): return {"message": "Hello World"}现在而不是返回: {"message": "Hello World"}...此响应将返回: { "message": "Hello World" }当然,您可能会找到比格式化 JSON 更好的方法来利用这一点。😉 默认响应类别创建 FastAPI 类实例或 APIRouter 时,您可以指定默认使用哪个响应类。 定义它的参数是 default_response_class 。 在下面的示例中, FastAPI 在所有路径操作中将默认使用 ORJSONResponse ,而不是 JSONResponse 。 from fastapi import FastAPI from fastapi.responses import ORJSONResponse app = FastAPI(default_response_class=ORJSONResponse) @app.get("/items/") async def read_items(): return [{"item_id": "Foo"}]Tip 您仍然可以像以前一样在路径操作中覆盖 response_class 。 Additional documentation您还可以使用 responses : Additional Responses in OpenAPI 在 OpenAPI 中声明媒体类型和许多其他详细信息。 © 2018 Sebastián RamírezLicensed under the MIT License. https://fastapi.tiangolo.com/advanced/custom-response/ |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |